﻿using System.Collections.Generic;
using System.Linq;
using System;
using UnityEngine;

namespace SSAAD {

	class JMPScienceSubject : IEquatable<JMPScienceSubject> {
		[KSPField]
		public ScienceSubject subject {get; private set;}

		public JMPScienceSubject(ScienceSubject s) {
			subject = s;
		}

		public bool Equals(JMPScienceSubject rhs) {
			if (rhs == null) {return false;}

			return subject.id == rhs.subject.id;
		}

		public override int GetHashCode() {
			return subject.id.GetHashCode();
		}
	};

	class JMPScienceStorageModule : PartModule {
		[KSPField]
		private Dictionary<JMPScienceSubject, float> scienceData;

		[KSPField]
		public float capacity = 0;

		[KSPField]
		public float capacityUsed {get; private set;}

		public override void OnAwake() {
			scienceData = new Dictionary<JMPScienceSubject, float>();
			capacityUsed = 0;
		}

		public void Start() {
			GameEvents.onVesselRecoveryProcessing.Add(handleRecoveryProcessing);
		}

		public void handleRecoveryProcessing(ProtoVessel pv, MissionRecoveryDialog d, float f) {
			foreach (JMPScienceSubject s in scienceData.Keys) {
				float sci = ResearchAndDevelopment.GetScienceValue(scienceData[s], ResearchAndDevelopment.GetSubjectByID(s.subject.id));

				if (ResearchAndDevelopment.Instance != null) {
					ResearchAndDevelopment.Instance.SubmitScienceData(scienceData[s],
						ResearchAndDevelopment.GetSubjectByID(s.subject.id)
					);
				}

				d.scienceEarned += sci;
				d.AddDataWidget(new MissionRecoveryDialog.ScienceSubjectWidget(s.subject, scienceData[s], sci));
			}

			GameEvents.onVesselRecoveryProcessing.Remove(handleRecoveryProcessing);

			scienceData.Clear();
			capacityUsed = 0;
			part.RequestResource("DataStorage", -capacity);
		}

		public float transmitHome(float data) {
			List<JMPScienceSubject> keys = scienceData.Keys.ToList();
			foreach(JMPScienceSubject s in keys) {
				float sent = Mathf.Min(data, scienceData[s]);
				
				if (ResearchAndDevelopment.Instance != null) {
					ResearchAndDevelopment.Instance.SubmitScienceData(data,
						ResearchAndDevelopment.GetSubjectByID(s.subject.id)
					);
				}

				part.RequestResource("DataStorage", -data);
				data -= sent;
				capacityUsed -= sent;
				scienceData[s] -= sent;
				if (scienceData[s] <= 0) {scienceData.Remove(s);}
			}

			return data;
		}

		public float handleData(float data, ScienceSubject s) {
			if (capacity > capacityUsed) {
				JMPScienceSubject sit = new JMPScienceSubject(s);
				float room = capacity - capacityUsed;
				room = Mathf.Min(room, data);

				data -= room;
				capacityUsed += room;

				if (scienceData.ContainsKey(sit)) { scienceData[sit] += room; }
				else { scienceData.Add(sit, room); }

				part.RequestResource("DataStorage", room);
			}

			return data;
		}
	}
}
